<template>
  <div>
    <el-dialog
      title="文档上传"
      v-model="showDialog"
      :before-close="close"
      @close="closed"
      @open="openDialog"
      width="800px"
      top="60px"
      append-to-body
    >
      <el-steps :active="activeIndex" finish-status="success" simple>
        <el-step title="选择文档" />
        <el-step title="完善属性" />
        <el-step title="完成提交" />
      </el-steps>
      <el-carousel
        height="500px"
        arrow="never"
        ref="carouselUpload"
        trigger="click"
        :autoplay="false"
        indicator-position="none"
        :loop="false"
        :initial-index="initialIndex"
      >
        <!-- S 选择文档 -->
        <el-carousel-item class="upload-carousel">
          <div v-for="(item, index) in maxUpload">
            <div
              :refIndex="'uploadRef' + index + '-' + maxUpload"
              class="upload-demo"
              :class="{ visible: index !== currentUpload }"
            >
              <el-upload
                :ref="'uploadRef' + index"
                drag
                :action="uploadSetting.action"
                :multiple="uploadSetting.multiple"
                :limit="uploadSetting.limit || 1"
                :disabled="uploadSetting.disabled"
                :on-remove="
                  (file, fileList) => {
                    return handleRemove(file, fileList, uploadSetting)
                  }
                "
                :on-success="
                  (response, file, fileList) => {
                    return handleSuccess(
                      response,
                      file,
                      fileList,
                      uploadSetting
                    )
                  }
                "
                :on-error="
                  (response, file, fileList) => {
                    return handleError(response, file, fileList, uploadSetting)
                  }
                "
                :on-exceed="
                  (file, fileList) => {
                    return handleExceed(file, fileList, uploadSetting)
                  }
                "
                :before-upload="
                  (file) => {
                    return beforeAvatarUpload(file, uploadSetting)
                  }
                "
                :on-preview="
                  (file) => {
                    return handlePreview(file, uploadSetting)
                  }
                "
                :on-change="
                  (file, fileList) => {
                    return handleChange(file, fileList, uploadSetting)
                  }
                "
                :on-progress="handleProgress"
                :headers="importHeaders"
                :auto-upload="!uploadSetting.noAutoUpload"
              >
                <el-icon class="el-icon--upload"><upload-filled /></el-icon>
                <div class="el-upload__text">点击或将文档拖拽到这里上传</div>
                <template #tip>
                  <div class="el-upload__tip">
                    <div>
                      {{ uploadSetting.bottomTip }}
                    </div>
                    <div>
                      {{ uploadSetting.bottomTipVideo }}
                    </div>
                  </div>
                </template>
              </el-upload>
            </div>
          </div>
        </el-carousel-item>
        <!-- E 选择文档 -->
        <!-- S 完善属性 -->
        <el-carousel-item class="upload-carousel">
          <el-form
            ref="formRef"
            :model="ruleForm"
            :rules="rules"
            label-width="120px"
            size="large"
            class="demo-ruleForm"
          >
            <el-form-item label="文档目录" prop="fileCategoryId">
              <tree-select
                ref="treeSelect"
                v-model:value="ruleForm.fileCategoryId"
                :options="fileCateTree"
                placeholder="请选择"
                :objMap="{
                  value: 'id',
                  label: 'categoryName',
                  children: 'children',
                }"
                @handleNodeClick="handleNodeClick"
              />
            </el-form-item>
            <el-form-item label="标题" prop="title">
              <el-input v-model="ruleForm.title" maxlength="64" clearable />
            </el-form-item>

            <el-form-item label="文档编码" prop="fileCode" class="code">
              <span class="code-head"
                ><span v-if="!deptPinyin">-</span>
                <el-tooltip
                  v-else
                  effect="dark"
                  :content="deptPinyin + '-' + ruleForm.fileCode"
                  placement="top-start"
                >
                  <span class="code-tooltip"> {{ deptPinyin }}-</span>
                </el-tooltip>
              </span>
              <el-input v-model="ruleForm.fileCode" maxlength="128" clearable />
            </el-form-item>
            <el-form-item label="文档版本号" prop="version">
              <el-input v-model="ruleForm.version" @input="_accountInput" />
            </el-form-item>
            <el-form-item label="关键字说明" prop="notes">
              <el-input
                v-model="ruleForm.notes"
                type="textarea"
                maxlength="64"
              />
            </el-form-item>
            <el-form-item label="文档摘要" prop="summary">
              <el-input
                v-model="ruleForm.summary"
                maxlength="512"
                type="textarea"
              />
            </el-form-item>
          </el-form>
        </el-carousel-item>
        <!-- E 完善属性 -->
        <!-- S 完成上传 -->
        <el-carousel-item class="upload-carousel">
          <el-result icon="success" title="提交完成" v-if="resStatus">
          </el-result>
          <el-result icon="error" :title="uploadError" v-else> </el-result>
          <!-- <el-result
            icon="success"
            title="提交完成"
            sub-title="Please follow the instructions"
          >
            <template #extra> deptNamePinyin </template>
          </el-result> -->
        </el-carousel-item>
        <!-- E 完成上传 -->
      </el-carousel>
      <div class="dialog-footer">
        <el-button
          v-if="(initialIndex === 1 || !resStatus) && initialIndex !== 0"
          type="primary"
          size="small"
          @click="handelActiveItem('prev')"
        >
          上一步
        </el-button>

        <el-button
          type="primary"
          v-if="initialIndex === 0"
          size="small"
          @click="handelActiveItem('next')"
        >
          下一步
          <el-icon class="el-icon--right"><ArrowRight /></el-icon>
        </el-button>
        <el-button
          v-if="initialIndex === 1"
          type="primary"
          size="small"
          @click="submit"
        >
          提交
        </el-button>
        <el-button
          v-if="initialIndex === 2"
          type="primary"
          size="small"
          @click="continueUpload"
        >
          继续上传
        </el-button>
        <el-button size="small" @click="close" v-if="initialIndex === 0"
          >取消</el-button
        >
        <el-button size="small" @click="back" v-if="initialIndex === 2"
          >返回</el-button
        >
      </div>
    </el-dialog>
  </div>
</template>

<script setup name="uploadDialog">
import {
  preUpload,
  getCategoryListHasViewAndUpload,
  removeUploadFile,
} from '@/api/fileManager'
import pinyin from 'js-pinyin'
import {
  getFullNamePinYin,
  getFileName,
  checkFile,
  submitForm,
  accountInput,
} from '../index.js'
import { deepClone, handleTree } from '@/utils'
const store = useStore()
const emits = defineEmits(['getList', 'close', 'update:open'])
const props = defineProps({
  open: {
    type: Boolean,
    default: false,
  },
  resStatus: {
    type: Boolean,
    default: true,
  },
  uploadError: {
    type: String,
    default: '位置错误',
  },
  fileCate: {
    type: Array,
    default: () => {
      return []
    },
  },
  // fileCateTree: {
  //   type: Array,
  //   default: () => {
  //     return []
  //   },
  // },
  uploadSetting: {
    type: Object,
    default: () => {
      return {}
    },
  },
})
const { proxy } = getCurrentInstance()
let initialIndex = ref(0)
let activeIndex = ref(0)
let currntFile = ref(null) // 当前上传文档列表
const maxUpload = ref(1) // 限制最大可以上传多要个文档（暂时没用，下面会自动增加下一次上传）
let fileAll = ref([]) // 上传文档列表
let fileSuccess = ref([]) // 上传文档成功列表
let fileError = ref([]) // 上传文档失败列表
let fileRemove = ref([]) // 上传文档取消列表
let filePending = ref([]) // 上传中文档
const fileCateTree = ref([])
const showDialog = computed({
  get() {
    return props.open
  },
  set(val) {
    emits('update:open', val)
  },
})

onMounted(() => {
  _getCategoryListHasViewAndUpload()
})
function _getCategoryListHasViewAndUpload() {
  getCategoryListHasViewAndUpload().then((res) => {
    if (res && res.success) {
      fileCateTree.value = handleTree(res.data, 'id')
    }
  })
}
// 获取上传中文档
function getUploadingFiles() {
  let result = []
  let _fileAll = fileAll.value
  let notPending = []
    .concat(fileSuccess.value)
    .concat(fileError.value)
    .concat(fileRemove.value)
  notPending = [...new Set(notPending)]
  for (let i = 0; i < _fileAll.length; i++) {
    let obj = _fileAll[i]
    let uid = obj.uid
    let isExist = false
    for (let j = 0; j < notPending.length; j++) {
      if (notPending[j].uid === uid) {
        isExist = true
        break
      }
    }
    if (!isExist) {
      result.push(obj)
    }
  }
  filePending.value = result
  console.log('上传中文档')
  console.log(filePending.value)
  console.log('上传中文档')
  noneFilePending()
}
function noneFilePending() {
  if (filePending.value.length === 0) {
    setTimeout(() => {
      uploadListClose()
    }, 1000)
  } else {
    store.commit('app/TOGGLE_UPLOADLIST', true)
  }
}
function uploadListClose() {
  store.commit('app/TOGGLE_UPLOADLIST', false)
}
let currentUpload = ref(0)
const importHeaders = reactive({
  Authorization: store.state.user.userInfo.token,
})
const deptName = store.state.user.userInfo.deptName
let deptPinyin = ref('')
if (deptName) {
  deptPinyin.value = pinyin.getCamelChars(deptName)
}
function handleNodeClick(node) {
  const id = node.id
  deptPinyin.value = getFullNamePinYin(id, props.fileCate, deptName)
}
const ruleForm = ref({
  module: '', // 文档大类
  fileCategoryId: '', //文档目录
  title: '', // 文档名
  fileCode: '', // 文档编码
  version: 'V1.0', // 版本号
  notes: '', //关键字说明
  summary: '', // 文档摘要
})
function _accountInput(val) {
  ruleForm.value.version = accountInput(val)
}
const rules = reactive({
  fileCategoryId: [
    {
      required: true,
      message: '请选择文档目录',
      trigger: 'change',
    },
  ],
  title: [
    { required: true, message: '请输入标题', trigger: 'blur' },
    { min: 0, max: 64, message: '长度不能超过64个字符', trigger: 'blur' },
  ],
  fileCode: [
    { required: true, message: '请输入文档编码', trigger: 'blur' },
    { min: 0, max: 128, message: '长度不能超过128个字符', trigger: 'blur' },
  ],
  version: [
    { required: true, message: '请输入文档版本号', trigger: 'blur' },
    { min: 0, max: 20, message: '长度不能超过20个字符', trigger: 'blur' },
  ],
})
function openDialog() {
  flag.value = true
}
function closed() {
  // 关闭前移除上传完成的文档
  if (!currntFile.value) {
    return
  }
  flagUploadOne.value = true
  currntFile.value = null
  setActiveItem(0)
}

function close() {
  for (const key in successFileTemp.value) {
    if (Object.hasOwnProperty.call(successFileTemp.value, key)) {
      const element = successFileTemp.value[key]
      removeUploadFile({
        id: element.response.data.id,
        path: element.response.data.path,
      })
    }
  }
  if (currentFile.value && currentFile.value.percentage !== 100) {
    proxy
      .$confirm('有文档正在上传，返回后将取消上传，是否继续', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
      .then(() => {
        const refName = 'uploadRef' + (maxUpload.value - 1)
        if (proxy.$refs[refName] && proxy.$refs[refName][0].abort) {
          proxy.$refs[refName][0].abort()
        }
        removeFile(currentFile.value)
        back()
      })
  } else {
    back()
  }
}

function back() {
  continueUpload()
  initialIndex.value = 0
  activeIndex.value = 0
  props.uploadSetting.fileList = []
  setActiveItem(initialIndex.value)
  proxy.$refs.formRef.resetFields()
  //proxy.$refs.treeSelect.clearHandle()
  if (deptName) {
    deptPinyin.value = pinyin.getCamelChars(deptName)
  }
  emits('close')
}

function submit() {
  submitForm(proxy).then((res) => {
    if (res) {
      const file = fileChange.value
      if (props.uploadSetting.fileList.length === 0) {
        proxy.$message.warning('请先上传一个文档')
        return
      }
      initialIndex.value++
      activeIndex.value++
      let filePrams = {
        fileName: file.name,
        fileSize: file.size,
        fileType: getFileName(file.name),
        fileUploadId: currentUploadId.value,
      }
      // 文档上传成功需要把返回的数据提交到后台
      let res = {}
      if (successFile.value.hasOwnProperty(file.uid)) {
        res = successFile.value[file.uid].response.data
        delete res.id
        filePrams = { ...filePrams, ...res }
      }
      ruleForm.value.detail = filePrams
      setActiveItem(initialIndex.value)
      // 复制一份防止点击提交下面修改fileCode后界面直接显示完整code的问题
      let ruleFormTemp = deepClone(ruleForm.value)
      ruleFormTemp.fileCode = deptPinyin.value + '-' + ruleForm.value.fileCode
      delete successFileTemp.value[currentFile.value.uid]
      emits('submit', ruleFormTemp)
    }
  })
  /*  if (!formRes) {
    return
  } */
}

// 设置下一个下载文档
function setNextUpload() {
  // 继续上传会自动添加一次上传组件
  if (currentUpload.value >= maxUpload.value) {
    maxUpload.value++
  }
}

function continueUpload() {
  currentUpload.value++
  flag.value = true
  props.uploadSetting.fileList = []
  proxy.$refs['formRef'].resetFields()
  currentFile.value = null
  //proxy.$refs.treeSelect.clearHandle()
  // 继续上传会自动添加一次上传组件
  setNextUpload()
  resetAction()
  setActiveItem(initialIndex.value)
}

function handelActiveItem(action) {
  if (action === 'next') {
    if (props.uploadSetting.fileList.length === 0) {
      proxy.$message.warning('请先上传一个文档')
      return
    }
    initialIndex.value++
    activeIndex.value++
  } else {
    initialIndex.value--
    activeIndex.value--
  }
  setActiveItem(initialIndex.value)
}

// 重置步进条和上传
function resetAction() {
  initialIndex.value = 0
  activeIndex.value = 0
}

// 设置上传步骤
function setActiveItem(value) {
  proxy.$refs.carouselUpload.setActiveItem(value)
}

function handleProgress(evt, file, fileList) {
  setUploadList(file)
}

// 移除一个文档
function removeFile(file) {
  let storeFileList = store.state.upload.uploadList
  delete storeFileList[file.uid]
  store.commit('SET_UPLOADLIST', storeFileList)
}

// 保存所有上传的文档
function setUploadList(file) {
  let storeFileList = store.state.upload.uploadList
  storeFileList[file.uid] = file
  store.commit('SET_UPLOADLIST', storeFileList)
}

function handleRemove(file, fileList, item) {
  fileRemove.value.push(file)
  console.log('fileRemove')
  console.log(fileRemove)
  removeFile(file)
  getUploadingFiles()
  item['value'] = ''
  item['fileList'] = []
  flag.value = true
  continueUpload()
  closed()
}
const successFile = ref({})
const successFileTemp = ref({}) // 保存所有上传成功但是没有提交的数据 ， 关闭弹窗删除服务器文件
function handleSuccess(res, file, fileList, item) {
  fileSuccess.value.push(file)
  successFile.value[file.uid] = file
  successFileTemp.value[file.uid] = file
  item['fileList'] = [file]
  flagUploadOne.value = true
  uploadOneFile()
  console.log('successFile')
  console.log(successFile)
  console.log(res)
  removeStoreUploading(file)
  getUploadingFiles()
}
// 上传成功移除store文档
function removeStoreUploading(file) {
  const uid = file.uid
  let storeFileList = store.state.upload.uploadList
  console.log(storeFileList)
  //delete storeFileList[uid]
  store.commit('SET_UPLOADLIST', storeFileList)
}
function handleError(res, file, fileList, item) {
  fileError.value.push(file)
  console.log('fileError')
  console.log(fileError)
  continueUpload()
  closed()
  getUploadingFiles()
}
// 上传文档个数限制超出提示
function handleExceed(file, fileList, item) {
  const limit = item.limit || 1
  if (fileList.length >= limit) {
    proxy.$message.warning(
      '最多上传' + limit + '个文档,请移除多余文档之后再进行上传'
    )
  }
}
// 上传前处理
function beforeAvatarUpload(file, item) {
  // 上传前获取文档id
  fileAll.value.push(file)
  currntFile.value = file
  console.log('fileAll')
  console.log(fileAll)
  getUploadingFiles()
  return true
}
// 上传前需要获取一个文档id，该事件会触发上传change回调多次，flag限制每次上传只回调一次
const flag = ref(true)
const currentUploadId = ref({})
const fileChange = ref({})
const currentFile = ref(undefined)
let uploadFile = ref([])
let flagUploadOne = ref(true)
let actionMap = ref({})
let uploadFileRefNameMap = ref({})
let uidMap = ref({})
function handleChange(file, item) {
  if (flag.value && file.status === 'ready') {
    const res = checkFile(file.raw, props.uploadSetting, proxy)
    if (!res) {
      const refName = 'uploadRef' + (maxUpload.value - 1)
      if (proxy.$refs[refName] && proxy.$refs[refName][0].clearFiles) {
        proxy.$refs[refName][0].clearFiles()
      }
      return
    }
    setCurrentFileAndName(file)
    flag.value = false
    fileChange.value = file
    props.uploadSetting['fileList'] = [file]
    // 上传前获取文档id
    preUpload()
      .then((res) => {
        if (res.code === 200) {
          currentUploadId.value = res.data
          const actionUrl =
            import.meta.env.VITE_APP_BASE_API + '/doc/file/upload/' + res.data
          props.uploadSetting.action = actionUrl
          actionMap.value[file.uid] = actionUrl
          uidMap.value[file.uid] = res.data
          setTimeout(() => {
            const refName = 'uploadRef' + (maxUpload.value - 1)
            uploadFile.value.push(refName)
            // 保存每次上传文档id与上传refname对应关系，下面获取文档上传地址
            uploadFileRefNameMap.value[refName] = file.uid
            setUploadList(file)
            uploadOneFile()
          }, 0)
        }
      })
      .catch((err) => {
        console.log(err)
        removeFile(file)
        currentFile.value = null
      })
  }
}
// 上传中的文档个数只能是一个
function uploadOneFile() {
  let length = uploadFile.value.length
  if (length > 0 && flagUploadOne.value) {
    flagUploadOne.value = false
    let refName = uploadFile.value[0]
    // 设置每次上传对应的上传地址
    props.uploadSetting.action =
      actionMap.value[uploadFileRefNameMap.value[refName]]
    if (proxy.$refs[refName] && proxy.$refs[refName][0].submit) {
      proxy.$refs[refName][0].submit()
    }
    uploadFile.value.shift()
  }
}
// 设置当前选择文档，并设置文档名
function setCurrentFileAndName(file) {
  currentFile.value = file
  if (currentFile.value && currentFile.value.name) {
    let name = currentFile.value.name
    if (name.indexOf('.') !== -1) {
      ruleForm.value.title = name.split('.')[0]
    } else {
      ruleForm.value.title = name
    }
  }
}
// 点击已上传文档钩子
function handlePreview(file, item) {
  emits('handlePreview', file)
}
</script>
<style lang="scss">
.upload-carousel {
  .el-progress__text {
    margin-top: 20px;
  }
}
</style>
<style scoped lang="scss">
:deep(.el-tree-select) {
  width: 100%;
}
.view {
  height: 400px;
  width: 500px;
  position: fixed;
  right: 0;
  bottom: 0;
}
.block {
  height: 400px;
  background: #fff;
  position: relative;
  z-index: -1;
}
/*(滑入)——从底部滑入,从底部滑出*/
.bottomToBottom-enter-active {
  animation: slideIn_bottom 1s;
}
/*(滑出)——从底部滑入,从底部滑出*/
.bottomToBottom-leave-active {
  animation: slideOut_bottom 1s;
}
/*滑入——从底部*/
@keyframes slideIn_bottom {
  0% {
    top: 100%;
  }

  100% {
    top: 0;
    z-index: 9 !important;
  }
}
/*滑出——从底部*/
@keyframes slideOut_bottom {
  0% {
    top: 0;
  }

  100% {
    top: 100%;
    z-index: 9 !important;
  }
}

.code-tooltip {
  max-width: 400px;
  display: block;
  text-overflow: ellipsis;
  overflow: hidden;
}
.demo-ruleForm {
  width: 90%;
  :deep(.el-form-item) {
    margin-bottom: 20px !important;
  }
  :deep(.el-input) {
    height: 36px !important;
    line-height: 36px !important;
  }
  .el-select {
    width: 100%;
  }
  .code {
    .code-head {
      flex: 1;
      width: 100%;
      margin-right: 6px;
      white-space: nowrap;
    }
    :deep(.el-form-item__content) {
      display: flex !important;
      width: 100%;
      flex-wrap: nowrap;
      align-items: center;
      flex: initial;
    }
  }
}
.upload-demo {
  text-align: center;
}
.visible {
  display: none;
}
.upload-carousel {
  display: flex;
  align-items: center;
  justify-content: center;
}
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  margin: 45px 0 0 0;
}
</style>
